#include "stdafx.h"
#include "Lexer_Combinator.h"

//Lexer_Result& Lexer_Result::operator+(LPTSTR _value)
//{
//	Lexer_Result* pResult = new Lexer_Result(GetMM());
//	int Len2 = wcslen(_value);
//	LPTSTR lpBuffer = new WCHAR[length + Len2 + 1];
//	if(length) wcsncpy(pResult->value,value,length);
//	if(Len2) wcsncpy(&pResult->value[length],_value,Len2);
//	pResult->value[length + Len2] = 0;
//	pResult->Length() = length + Len2;
//	pResult->SetResult(TRUE);
//	((Lexer_MemoryManager*)MM)->AddString(pResult->value);
//	MM->AddCombinatorResult(pResult);
//	return *pResult;
//}

Lexer_Result& Lexer_Result::operator+(Lexer_Result& _value)
{
	Lexer_Result* pResult = new Lexer_Result(GetMM());
	pResult->value = new WCHAR[length + _value.length + 1];
	if(length) wcsncpy(pResult->value,value,length);
	if(_value.length) wcsncpy(&pResult->value[length],_value.value,_value.length);
	pResult->value[length + _value.length] = 0;
	pResult->Length() = length + _value.length;
	pResult->SetResult(TRUE);
	((Lexer_MemoryManager*)MM)->AddString(pResult->value);
	MM->AddCombinatorResult(pResult);
	return *pResult;
}

Lexer_Ch::Lexer_Ch(WCHAR _value,BOOL _Not) : value(_value),Not(_Not),
	Lexer_Combinator((Combinator_MemoryManager<LPTSTR,Lexer_Result>*)&g_Lexer_MemoryManager)
{
}

Lexer_Result Lexer_Ch::Parser(LPTSTR& input)
{
	Lexer_Result Result(0,GetMM());
	if(*input == 0)
	{
		//Result.SetResult(TRUE);
		return Result;
	}
	if(value == 0)
	{
		Result.Value() = &value;
		Result.Length() = 1;
		Result.SetResult(TRUE);
		input++;
	}
	else if(Not)
	{
		if(input[0] != value)
		{
			Result.Value() = &value;
			Result.Length() = 1;
			Result.SetResult(TRUE);
			input++;
		}
	}
	else
	{
		if(input[0] == value)
		{
			Result.Value() = &value;
			Result.Length() = 1;
			Result.SetResult(TRUE);
			input++;
		}
	}
	return Result;
}

WCHAR Lexer_Ch::Value()
{
	return value;
}

Lexer_Str::Lexer_Str(LPTSTR _value,BOOL _Not) : value(_value),Not(_Not),
	Lexer_Combinator((Combinator_MemoryManager<LPTSTR,Lexer_Result>*)&g_Lexer_MemoryManager)
{
}

Lexer_Result Lexer_Str::Parser(LPTSTR& input)
{
	Lexer_Result Result(0,GetMM());
	if(*input == 0)
	{
		Result.SetResult(TRUE);
		return Result;
	}
	if(Not)
	{
		int Len1 = wcslen(value);
		int Len2 = wcslen(input);
		int i = 0;
		int j = 0;
		while(input[i])
		{
			if(input[i] == value[j]) j++;
			else j = 0;
			if(j == Len1)
			{
				Result.Value() = input;
				Result.Length() = i - j;
				Result.SetResult(TRUE);
				input += i - j + 1;
				return Result;
			}
			i++;
		}
		Result.Value() = input;
		Result.Length() = Len2;
		Result.SetResult(TRUE);
		input += Len2;
		return Result;
	}
	else
	{
		int Len1 = wcslen(value);
		int Len2 = wcslen(input);
		if(Len1 <= Len2)
		{
			int i = 0;
			while(input[i] && i < Len1)
			{
				if(value[i] != input[i]) return Result;
				i++;
			}
			Result.Value() = value;
			Result.Length() = Len1;
			Result.SetResult(TRUE);
			input += Len1;
		}
	}
	return Result;
}

Lexer_Result::Lexer_Result() : length(0),CombinatorResult<LPTSTR,Lexer_Result>((Combinator_MemoryManager<LPTSTR,Lexer_Result>*)&g_Lexer_MemoryManager)
{
}

Lexer_Combinator_Node::Lexer_Combinator_Node() : Combinator_Node<LPTSTR,Lexer_Result>((Combinator_MemoryManager<LPTSTR,Lexer_Result>*)&g_Lexer_MemoryManager)
{
}

Lexer_Combinator_Node& Lexer_Combinator_Node::operator-(Lexer_Combinator_Node& _value)
{
	Lexer_Ch* pLeft = (Lexer_Ch*)this->Value();
	Lexer_Ch* pRight = (Lexer_Ch*)_value.value;
	Combinator_List<LPTSTR,Lexer_Result>* pList = new Combinator_List<LPTSTR,Lexer_Result>(GetMM());
	for(WCHAR i=pLeft->Value();i<=pRight->Value();i++)
	{
		Lexer_Ch* pCh = new Lexer_Ch(i);
		Lexer_Combinator_Node* pNode = new Lexer_Combinator_Node(pCh);
		pList->Add(*pNode);
		((Lexer_MemoryManager*)MM)->AddCh(pCh);
		((Lexer_MemoryManager*)MM)->AddCombinatorNode(pNode);
	}
	Lexer_Combinator_Node* pNode = new Lexer_Combinator_Node(pList);
	((Lexer_MemoryManager*)MM)->AddList(pList);
	((Lexer_MemoryManager*)MM)->AddCombinatorNode(pNode);
	return *pNode;
}